package com.dankegongyu.lib.common.util;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import androidx.annotation.Nullable;

/**
 * @author wupuquan
 * @version 1.0
 * @since 2018/1/31 20:17
 */
public final class DKActivityManager {

    private Application sApplication;
    private final List<Activity> mActivities = Collections.synchronizedList(new LinkedList<Activity>());

    private DKActivityManager() {

    }

    private static class SingletonHolder {
        private static final DKActivityManager sInstance = new DKActivityManager();
    }

    public static DKActivityManager getInstance() {
        return SingletonHolder.sInstance;
    }

    public void init(Application application) {
        if (sApplication == null) {
            sApplication = application;
            if (sApplication != null && getProcessName(sApplication).endsWith(sApplication.getPackageName())) {
                sApplication.registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks);
            }
        }
    }

    /**
     * 获取当前进程的名字
     */
    private String getProcessName(Context cxt) {
        int pid = android.os.Process.myPid(); // Returns the identifier of this process
        ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
        if (runningApps == null) {
            return "";
        }
        for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
            if (procInfo.pid == pid) {
                return procInfo.processName;
            }
        }
        return "";
    }

    private Application.ActivityLifecycleCallbacks mActivityLifecycleCallbacks = new Application.ActivityLifecycleCallbacks() {
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            pushActivity(activity);
        }

        @Override
        public void onActivityStarted(Activity activity) {

        }

        @Override
        public void onActivityResumed(Activity activity) {

        }

        @Override
        public void onActivityPaused(Activity activity) {

        }

        @Override
        public void onActivityStopped(Activity activity) {

        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

        }

        @Override
        public void onActivityDestroyed(Activity activity) {
            popActivity(activity);
        }
    };

    private boolean pushActivity(Activity activity) {
        synchronized (mActivities) {
            return mActivities.add(activity);
        }
    }

    private boolean popActivity(Activity activity) {
        synchronized (mActivities) {
            return activity != null && mActivities.remove(activity);
        }
    }

    public Activity getTopActivity() {
        synchronized (mActivities) {
            if (mActivities.isEmpty()) return null;
            return mActivities.get(mActivities.size() - 1);
        }
    }

    public boolean finishActivity(Activity activity) {
        synchronized (mActivities) {
            try {
                if (activity != null) {
                    activity.finish();
                    return mActivities.remove(activity);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return false;
        }
    }

    public void finishAllActivities() {
        synchronized (mActivities) {
            try {
                for (Activity activity : mActivities) {
                    if (activity != null) {
                        activity.finish();
                    }
                }
                mActivities.clear();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 保留栈底Activity，其他都finish
     */
    public void finishAllActivitiesRemainBottom() {
        synchronized (mActivities) {
            try {
                for (int i = mActivities.size() - 1; i > 0; ) {
                    Activity activity = mActivities.get(i);
                    if (activity != null) {
                        activity.finish();
                        mActivities.remove(activity);
                    }
                    i = mActivities.size() - 1;
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 删除Activity栈中 目标Activity下面的Activity
     * 场景：MainActivity一般在栈底，如果打开MainActivity之前点击启动广告进入了WebActivity且
     * WebActivity正好是singleTask，此时点MainActivity中的banner广告打开WebActivity，由于
     * singleTask导致MainActivity出栈了。。点返回就退到手机桌面了。。2333，所以打开MainActivity
     * 后需要移除栈中MainActivity下面的Activity
     *
     * @param targetActivity 目标Activity
     */
    public void finishActivitiesBelowTargetActivity(Activity targetActivity) {
        synchronized (mActivities) {
            try {
                int targetActivityPosition = -1;
                List<Activity> shouldFinish = new ArrayList<>();
                for (int i = mActivities.size() - 1; i >= 0; i--) {
                    Activity activity = mActivities.get(i);
                    if (targetActivityPosition == -1 && TextUtils.equals(activity.getClass().getName(), activity.getClass().getName())) {
                        targetActivityPosition = i;
                        DKLog.d(i + "目标Activity: " + targetActivity.getClass().getName());
                    }
                    if (i < targetActivityPosition) {
                        shouldFinish.add(activity);
                    }
                }
                for (Activity activity : shouldFinish) {
                    DKLog.d("关闭Activity: " + activity.getClass().getName());
                    activity.finish();
                    mActivities.remove(activity);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 这里主要处理RoomDetailActivity重复打开的问题，
     * 暂定为保留两个RoomDetailActivity，当打开第三个时finish第一个
     *
     * @param maxSize  最多保留几个Activity的实例
     * @param activity activity名称
     */
    public void findAndFinishFirstActivity(int maxSize, Activity activity) {
        if (activity == null) {
            return;
        }
        synchronized (mActivities) {
            try {
                List<Integer> positions = new ArrayList<>();
                for (int i = mActivities.size() - 1; i >= 0; i--) {
                    Activity index = mActivities.get(i);
                    if (index == null) {
                        continue;
                    }
                    if (TextUtils.equals(index.getClass().getName(), activity.getClass().getName())) {
                        positions.add(i);
                        if (positions.size() > maxSize) {
                            // 大于2时把最后找到的(即打开的第一个关闭)
                            try {
                                mActivities.get(positions.get(positions.size() - 1)).finish();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            break;
                        }
                    }
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }

    @Nullable
    public Activity find(Class<? extends Activity> clz) {
        synchronized (mActivities) {
            for (Activity activity : mActivities) {
                if (TextUtils.equals(activity.getClass().getName(), clz.getName())) {
                    return activity;
                }
            }
        }
        return null;
    }
}